<?php
/**
 * Class used to handle file uploads
 *
 * @author André Silva
 */
class Upload {
	/**
	 * Simple filename without type
	 * @var string
	 */
	public $filename;
	/**
	 * File type
	 * @var string
	 */
	protected $type;
	/**
	 * Real path to the upload
	 * @var string
	 */
	public $path;
	/**
	 * Max filesize =  2097152 ( 2M )
	 * @var int
	 */
	public $maxSize = 2097152;
	/**
	 * True if must check filesize
	 * @var boolean
	 */
	public $checkSize = true;
	/**
	 * True if must check file type
	 * @var boolean
	 */
	public $checkType = true;
	/**
	 * $_FILE variable
	 * @var array
	 */
	protected $upload;
	/**
	 * If the upload is valid
	 * @var boolean
	 */
	protected $valid = false;
	/**
	 * Alloweb types
	 * @var array
	 */
	public static $types = array('jpg', 'gif', 'png', 'doc', 'pdf', 'xls', 'ppt', 'zip', 'rar');
	/**
	 * Upload errors
	 * @var array
	 */
	public static $errors = array(
			UPLOAD_ERR_OK => 'There is no error, the file uploaded with success.',
			UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
			UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
			UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
			UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
			UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
			UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
			UPLOAD_ERR_EXTENSION => 'File upload stopped by extension.'
	);

	/**
	 * Try create a new upload instance
	 * @param string $upload Upload key for $_FILE
	 * @param string $path Real path
	 * @param string $filename Upload filename
	 */
	function __construct($upload, $path = null, $filename = null) {
		$this->upload = $_FILES[$upload];

		$ext = explode('.', $this->upload['name']);
		$this->type = end($ext);

		$this->filename = empty($filename) ? $this->upload['name'] : $filename;
		$this->filename .= '.' . $this->type;

		$this->path = $path;
		$this->valid = false;
		$this->checkSize = true;
		$this->checkType = true;
	}

	/**
	 * Check if the upload is valid
	 * @return boolean
	 */
	public function isValid() {
		if ($this->valid === true) {
			return true;
		}

		if (isset($this->upload['error']) && $this->upload['error'] != 0) {
			throw new Exception('Upload error: '.self::$errors[$this->upload['error']].' (' . $this->upload['name'].')');
		}

		if (!is_uploaded_file($this->upload['tmp_name'])) {
			throw new Exception('Upload error: unknow (' . $this->upload['name'].')');
		}

		if ($this->checkType) {
			if (!in_array($this->type, self::$types)) {
				throw new Exception('Upload error: invalid type ' . $this->upload['type'].' (' . $this->upload['name'].')');
			}
		}

		if ($this->checkSize) {
			if ($this->upload['size'] > $this->maxSize) {
				throw new Exception('Upload error: file exceeds max size (' . $this->upload['name'].')');
			}
		}

		$this->valid = true;
		return true;
	}

	/**
	 * Try save the uploaded file
	 * @return boolean
	 */
	public function save() {
		if ($this->isValid() === false) {
			return false;
		}
		if (!file_exists($this->path)) {
			mkdir($this->path, 0777, true);
		}
		move_uploaded_file($this->upload['tmp_name'], $this->path . $this->filename);

		return true;
	}
}

?>